﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TRPOP.CMS.RegAssembly;
using TRPOP.Common;
using System.Text.RegularExpressions;
/*
 * 
 *   读取模板文件，一行一行的读取，并解析相关的语法，转换为CS文件
 * 
 */
namespace TRPOP.CMS.Template.GenerateCS
{
    /// <summary>
    /// 生成 CS文件  生成DLL文件 执行DLL文件
    /// </summary>
    public class Access
    {

        /// <summary>
        /// 生成CS文件
        /// </summary>
        /// <param name="oCurrentPageInfo"></param>
        /// <returns></returns>
        public bool GenerateCSFile(TemplateDllPageInfo oCurrentPageInfo)
        {
            //如果生成的程序文件地址为空 ，则返回false
            if (oCurrentPageInfo.strTemplateCsFilePath.IsEmpty())
                return false;

            bool IsGenerateCsFile = true;
            StringBuilder strBuilderHtml = new StringBuilder();
            StringBuilder strBuilderCS = new StringBuilder();

            #region 读取模板文件内容
            if (!FileUtil.IsExist(oCurrentPageInfo.strTemplateFilePath))
            {
                oCurrentPageInfo.strErrorInfo = "模板文件不存在,模板文件地址:" + oCurrentPageInfo.strTemplateFilePath;
                oCurrentPageInfo.IsGenerateCsFile = false;
                return false;
            }
            strBuilderHtml.Append(FileUtil.ReadFile(oCurrentPageInfo.strTemplateFilePath));
            #endregion

            #region 解析 include 标签，将include的file内容加载进来
            BaseOperInclude(strBuilderHtml, oCurrentPageInfo);
            #endregion

            #region 去掉模板里的注释
            RemoveNote(strBuilderHtml);
            #endregion

            // Csharp代码开始
            CommonCodeForCSFile.BaseOperStart(strBuilderCS, oCurrentPageInfo);

            //分行处理数据  针对每一行数据，进行cms tag处理
            string strBaseTab = "\t\t\t";
            string[] Separators = new string[] { Environment.NewLine };
            string[] aryString = strBuilderHtml.ToString().Split(Separators, StringSplitOptions.None);
            int intIndexRow = 0;
            foreach (string LineString in aryString)
            {
                intIndexRow++;
                if (LineString.IsEmpty())
                    continue;
                strBuilderCS.Append(ConvertTags.ConvertTagsAccess(LineString, ref strBaseTab, intIndexRow));
            }

            // Csharp代码结束
            CommonCodeForCSFile.BaseOperEnd(strBuilderCS, oCurrentPageInfo);

            // 生成文件
            FileUtil.WriteFile(oCurrentPageInfo.strTemplateCsFilePath, strBuilderCS.ToString());

            return IsGenerateCsFile;
        }

        /// <summary>
        /// 生成DLL文件
        /// </summary>
        /// <param name="oCurrentPageInfo"></param>
        /// <returns></returns>
        public bool GenerateDLLFile(TemplateDllPageInfo oCurrentPageInfo)
        {
            //cs文件不存在 则直接返回false
            if (oCurrentPageInfo.strTemplateCsFilePath.IsEmpty() || !FileUtil.IsExist(oCurrentPageInfo.strTemplateCsFilePath))
            {
                oCurrentPageInfo.strErrorInfo = "CS文件不存在";
                return false;
            }

            bool blnReturn = GenerateCodeFile.GenerateDll(oCurrentPageInfo.strTemplateCsFilePath);

            if (blnReturn && !FileUtil.IsExist(oCurrentPageInfo.strTemplateDLLPath))
            {
                oCurrentPageInfo.strErrorInfo = "DLL文件生成失败，存在语法错误，请检查模板语法或查看对应的cs文件";
                return false;
            }
            return blnReturn;

        }

        /// <summary>
        /// 执行DLL文件
        /// </summary>
        /// <param name="oTemplateDllPageInfo"></param>
        /// <returns></returns>
        public TemplateDllPageInfo ExecuteteDll(TemplateDllPageInfo oTemplateDllPageInfo)
        {
            return ExecuteTemplate.ExecutetemplateDll(oTemplateDllPageInfo);
        }

        #region include all files

        private static Tags_Include oTags_Include = new Tags_Include();
        /// <summary>
        /// 将include替换为文件的内容
        /// </summary>
        /// <param name="strBuild"></param>
        /// <param name="oTemplateDllPageInfo"></param>
        private static void BaseOperInclude(StringBuilder strBuild, TemplateDllPageInfo oTemplateDllPageInfo)
        {
            MatchCollection oMatches = oTags_Include.Matches(strBuild.ToString());
            while (oMatches.Count > 0)
            {
                foreach (Match oincludeMatch in oMatches)
                {
                    string strTagsValue = string.Empty;
                    Dictionary<string, string> oDictionary = ConvertTags.GetAttribute(oincludeMatch.Groups["attribute"].ToString());
                    if (oDictionary.ContainsKey("file"))
                    {
                        if (oDictionary["file"].Trim().ToLower().StartsWith("http://"))
                        {
                            strTagsValue = TRPOP.Common.DownURLFile.ReadUrlFile(oDictionary["file"].Trim().ToLower());
                        }
                        else
                        {
                            string strPhysicPath = Common.Util.GetMapPath(
                                GetFileRoot(oDictionary["file"], oTemplateDllPageInfo.strCurrentFolder)
                                );
                            if (FileUtil.IsExist(strPhysicPath))
                            {
                                strTagsValue = FileUtil.ReadFile(strPhysicPath);
                            }
                        }
                    }
                    strBuild.Replace(oincludeMatch.Value, strTagsValue);
                }
                oMatches = oTags_Include.Matches(strBuild.ToString());
            }
        }

        /// <summary>
        /// 根据制定的file路径 模板所在文件夹路径 组合成为 绝对路径
        /// </summary>
        /// <param name="strNewLocation">制定的file的路径</param>
        /// <param name="strCurrentFolder">父模板文件所在的文件夹路径【需绝对路径】</param>
        /// <returns></returns>
        public static string GetFileRoot(string strNewLocation, string strCurrentFolder)
        {
            if (strNewLocation.StartsWith("/"))
                strNewLocation = strNewLocation.Remove(0, 1);
            if (strCurrentFolder.EndsWith("/"))
                strCurrentFolder = strCurrentFolder.Remove(strCurrentFolder.Length - 1, 1);
            if (strNewLocation.StartsWith("../"))
            {
                while (strNewLocation.StartsWith("../") && strCurrentFolder.Contains("/"))
                {
                    strNewLocation = strNewLocation.Remove(0, 3);
                    strCurrentFolder = strCurrentFolder.Remove(strCurrentFolder.LastIndexOf("/"));
                }
            }
            return strCurrentFolder + "/" + strNewLocation;
        }

        #endregion

        #region RemoveNote

        /// <summary>
        /// 去掉模板里的注释
        /// </summary>
        /// <param name="strBuilderHtml"></param>
        public static void RemoveNote(StringBuilder strBuilderHtml)
        {
            TRPOP.CMS.RegAssembly.Tags_Note oTags_Note = new TRPOP.CMS.RegAssembly.Tags_Note();
            MatchCollection oMatchCollection = oTags_Note.Matches(strBuilderHtml.ToString());
            foreach (Match oMatch in oMatchCollection)
            {
                TagsReplace(strBuilderHtml, oMatch, "");
            }
        }
        /// <summary>
        /// 替换标签 
        /// </summary>
        /// <param name="strBuilderHtml"></param>
        /// <param name="oMatch"></param>
        /// <param name="strTagsValue"></param>
        public static void TagsReplace(StringBuilder strBuilderHtml, Match oMatch, string strTagsValue)
        {
            int intIndex = strBuilderHtml.ToString().IndexOf(oMatch.Value);
            strBuilderHtml.Remove(intIndex, oMatch.Value.Length);
            if (!strTagsValue.IsEmpty())
            {
                strBuilderHtml.Insert(intIndex, strTagsValue);
            }
        }
        #endregion
    }
}
